#include <iostream>

#include "component/middleware/util/binio_test/binio.h"

int main(int argc, char const* argv[]) {
  using namespace ::component::middleware::util::binio;
  char buf[4096] = {};
  char* data_buf = buf;
  {
    auto& v = CInt::Create(data_buf, 12345);
    std::cout << v.GetTypeName() << std::endl;
    std::cout << "BufDataSize=" << v.GetBufDataSize() << std::endl;
    std::cout << "value=" << v.GetValue() << std::endl;
  }
  {
    auto& v = CString::Create(data_buf, "abcde");
    std::cout << v.GetTypeName() << std::endl;
    std::cout << "BufDataSize=" << v.GetBufDataSize() << std::endl;
    std::cout << "value=" << v.GetValue() << std::endl;
  }
  {
    std::vector<int> values = {3, 4, 5};
    auto& v = CArray<CInt, 5>::Create(data_buf, std::span<int>{values});
    std::cout << v.GetTypeName() << std::endl;
    std::cout << "BufDataSize=" << v.GetBufDataSize() << std::endl;
    std::cout << "value=";
    for (auto&& elem : v.GetValue()) {
      std::cout << elem.GetValue() << ',';
    }
    std::cout << std::endl;
  }
  {
    std::vector<std::string_view> values = {"abc", "defg"};
    auto& v = CArray<CString, 5>::Create(data_buf, std::span<std::string_view>(values));
    std::cout << v.GetTypeName() << std::endl;
    std::cout << "BufDataSize=" << v.GetBufDataSize() << std::endl;
    std::cout << "value=";
    for (auto&& elem : v.GetValue()) {
      std::cout << elem.GetValue() << ',';
    }
    std::cout << std::endl;
  }
  {
    std::vector<int> values = {1, 2, 3};
    auto& v = CVector<CInt>::Create(data_buf, std::span<int>(values));
    std::cout << v.GetTypeName() << std::endl;
    std::cout << "BufDataSize=" << v.GetBufDataSize() << std::endl;
    std::cout << "value=";
    for (auto&& elem : v.GetValue()) {
      std::cout << elem.GetValue() << ',';
    }
    std::cout << std::endl;
  }
  {
    std::vector<std::string_view> values = {"abc", "defg"};
    auto& v = CVector<CString>::Create(data_buf, std::span<std::string_view>(values));
    std::cout << v.GetTypeName() << std::endl;
    std::cout << "BufDataSize=" << v.GetBufDataSize() << std::endl;
    std::cout << "value=";
    for (auto&& elem : v.GetValue()) {
      std::cout << elem.GetValue() << ',';
    }
    std::cout << std::endl;
  }
  if (data_buf > std::end(buf)) {
    std::cerr << "Overflow!" << std::endl;
    std::abort();
    return 0;
  }
  {
    char buf[4096] = {};
    std::vector<std::string_view> values{"abc", "defg", "hijk", "lmn"};
    ::binio::BufObj<CVector<CString>> str_vec(buf, std::span<std::string_view>(values));
    auto idx = -1;
    for (auto&& i : str_vec.GetValue()) {
      std::cout << "str_vec[" << ++idx << "] = " << i.GetValue() << std::endl;
    }
  }
  {
    char buf[4096] = {};
    ::binio::BufObj<TestStruct> test(buf);
    test.ipv4()[0].SetValue(245);
    test.version().major().SetValue(2);
    std::cout << "ipv4=" << static_cast<int>(test.ipv4()[0].GetValue()) << '.'
              << static_cast<int>(test.ipv4()[1].GetValue()) << '.'
              << static_cast<int>(test.ipv4()[2].GetValue()) << '.'
              << static_cast<int>(test.ipv4()[3].GetValue()) << std::endl;
    std::cout << "version=" << test.version().major().GetValue() << '.'
              << test.version().minor().GetValue() << std::endl;
    std::cout << std::endl << test.version().GetTypeDesc() << std::endl;
    std::cout << std::endl << test.GetTypeDesc() << std::endl;
  }
  return 0;
}
